#include <cad-slicer/slicer.h>
#include <iostream>

#include <assimp/Importer.hpp>

#include <cad-slicer/export.h>
#include <cad-slicer/object-transform.h>


int main(int argc, char** argv)
{
  if (argc < 8)
  {
    std::cerr
        << "usage: " << argv[0]
        << " <3d_model> <object_scale>"
           " <slicing_box_dimension_x>"
           " <slicing_box_dimension_y>"
           " <slicing_box_dimension_z>"
           " <slicing_step>"
           " <output_format:png or svg or svgs>"
        << std::endl;
    return 1;
  }

  std::string format = argv[7];

  float scale = std::atof(argv[2]);
  cadslicer::slicer::parameters param;
  param.step =std::atof(argv[6]);
  param.slicing_box_dimensions[0] = std::atof(argv[3]);
  param.slicing_box_dimensions[1] = std::atof(argv[4]);
  param.slicing_box_dimensions[2] = std::atof(argv[5]);

  Assimp::Importer object;
  object.ReadFile(argv[1], 0);

  cadslicer::apply_transform(
        object,
        {
          scale, 0.f  , 0.f  , 0.f,
          0.f  , scale, 0.f  , 0.f,
          0.f  , 0.f  , scale, 0.f,
          0.f  , 0.f  , 0.f  , 1.f
        });

  cadslicer::slicer slicer(param);

  try
  {
    if (format == "png")
    {
      auto save_slice =
          [&param](cadslicer::slice const& slice)
      {
        char buffer[100];
        std::snprintf(buffer, 100, "/tmp/slicing/%2.5f.png", slice.get_z());
        cadslicer::export_to_png(
              slice,
        {param.slicing_box_dimensions[0],
         param.slicing_box_dimensions[1]},
        {640,640},
              buffer);
      };

      slicer.set_slice_post_treatment(save_slice);

      slicer(object);
    }
    else if (format == "svg")
    {
      auto save_slice =
          [&param](cadslicer::slice const& slice)
      {
        char buffer[100];
        std::snprintf(buffer, 100, "/tmp/slicing/%2.5f.svg", slice.get_z());
        cadslicer::export_to_svg(
              slice,
        {param.slicing_box_dimensions[0],
         param.slicing_box_dimensions[1]},
        {640,640},
              buffer);
      };

      slicer.set_slice_post_treatment(save_slice);

      slicer(object);
    }
    else if (format == "svgs")
    {
      slicer(object);
      cadslicer::export_to_svg(
            slicer.get_slices(),
      {param.slicing_box_dimensions[0],
       param.slicing_box_dimensions[1]},
      {640,640},
            "/tmp/slicing/output.svg");
    }
    else
    {
      std::cerr << "unknown format: " << format << std::endl;
      return 1;
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Error: " << e.what() << std::endl;
  }

  return 0;
}
